package zk.weart.core.aliyun.oss;

import cn.hutool.core.date.DateUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.internal.OSSUtils;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectResult;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;

/**
 * @author scjia
 */
public class OSSTools {

    /**
     * 上传文件
     *
     * @param endpoint
     * @param accessKeyId
     * @param accessKeySecret
     * @param bucketName
     * @param fileName        matchId/aa.jpg
     * @param fileBytes
     * @param publicFlag      bucket默认私有 true 公共读   false  私有读    除了apk下载都用私有访问，防止被别人猜测扫库
     */
    public  PutObjectResult putOSS(String endpoint,
                                         String accessKeyId,
                                         String accessKeySecret,
                                         String bucketName,
                                         String fileName,
                                         byte[] fileBytes,
                                         Boolean publicFlag) {

        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        PutObjectResult objectResult = ossClient.putObject(bucketName, fileName, new ByteArrayInputStream(fileBytes));
        if (publicFlag) {
            ossClient.setObjectAcl(bucketName, fileName, CannedAccessControlList.PublicRead);
        }
        ossClient.shutdown();
        return objectResult;
    }


    public  PutObjectResult putOSS(String endpoint,
                                   String accessKeyId,
                                   String accessKeySecret,
                                   String bucketName,
                                   String fileName,
                                   InputStream inputStream,
                                   Boolean publicFlag) {

        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        PutObjectResult objectResult = ossClient.putObject(bucketName, fileName, inputStream);
        if (publicFlag) {
            ossClient.setObjectAcl(bucketName, fileName, CannedAccessControlList.PublicRead);
        }
        ossClient.shutdown();
        return objectResult;
    }

    /**
     * 上传文件 私有独写
     *
     * @param endpoint
     * @param accessKeyId
     * @param accessKeySecret
     * @param bucketName
     * @param fileName        matchId/aa.jpg
     * @param fileBytes
     */
    public  void putOSSPrivate(String endpoint,
                                     String accessKeyId,
                                     String accessKeySecret,
                                     String bucketName,
                                     String fileName,
                                     byte[] fileBytes) {

        putOSS(endpoint, accessKeyId, accessKeySecret, bucketName, fileName, fileBytes, false);
    }


    public  String getFileUrl(String endpoint,String accessKeyId,String accessKeySecret, String bucketName,String ossFileKey, int expires) {
        OSS client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        URL url = client.generatePresignedUrl(bucketName, ossFileKey, DateUtil.offsetDay(new Date(), expires));
        String path = url.toString();
        return path;
    }

    /**
     * 返回文件
     *
     * @param endpoint
     * @param accessKeyId
     * @param accessKeySecret
     * @param bucketName
     * @param fileName
     * @return
     * @throws Exception
     */
    public  InputStream getOSSInputStream(String endpoint,
                                                String accessKeyId,
                                                String accessKeySecret,
                                                String bucketName,
                                                String fileName) throws Exception {

        InputStream inputStream = null;
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        try {


            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            OSSObject ossObject = ossClient.getObject(bucketName, fileName);

            InputStream ossIn = ossObject.getObjectContent();
            /**
             * 为什么不直接返回 ossIn
             * 因为 ossObject.close()后 ossIn也将会关闭
             * 造成其他调用此方法的线程 在使用ossIn的时候
             * 获取到的是一个已经被关闭的流
             * inputStream 应该在调用者线程中关闭
             */

            if (ossIn != null) {
                byte[] bts = new byte[1024];
                int len = -1;
                while ((len = ossIn.read(bts)) != -1) {
                    out.write(bts, 0, len);
                }
            }

            byte[] bytes = out.toByteArray();

            // 关闭OSSClient。
            ossObject.close();
            ossClient.shutdown();

            inputStream = new ByteArrayInputStream(bytes);

        } catch (Exception e) {

            e.printStackTrace();
        } finally {
            if (out != null) {
                out.flush();
                out.close();
            }
        }

        return inputStream;

    }


    public  byte[] getOSSBytes(String endpoint,
                                     String accessKeyId,
                                     String accessKeySecret,
                                     String bucketName,
                                     String fileName) throws Exception {

        ByteArrayOutputStream out = new ByteArrayOutputStream();

        try {


            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            OSSObject ossObject = ossClient.getObject(bucketName, fileName);

            InputStream ossIn = ossObject.getObjectContent();
            /**
             * 为什么不直接返回 ossIn
             * 因为 ossObject.close()后 ossIn也将会关闭
             * 造成其他调用此方法的线程 在使用ossIn的时候
             * 获取到的是一个已经被关闭的流
             * inputStream 应该在调用者线程中关闭
             */

            if (ossIn != null) {
                byte[] bts = new byte[1024];
                int len = -1;
                while ((len = ossIn.read(bts)) != -1) {
                    out.write(bts, 0, len);
                }
            }

            byte[] bytes = out.toByteArray();

            // 关闭OSSClient。
            ossObject.close();
            ossClient.shutdown();
            return bytes;

        } catch (Exception e) {

            e.printStackTrace();
        } finally {
            if (out != null) {
                out.flush();
                out.close();
            }
        }

        return null;

    }











}
